<?php

require_once 'vendor/autoload.php';

use Smalot\Cups\Builder\Builder;
use Smalot\Cups\Manager\JobManager;
use Smalot\Cups\Manager\PrinterManager;
use Smalot\Cups\Model\Job;
use Smalot\Cups\Transport\Client;
use Smalot\Cups\Transport\ResponseParser;
use Http\Client\Socket\Client as HttpClient;

/**
 * EPSON L4260 Series IP地址测试脚本
 * 打印机IP: 10.1.0.12
 */

class EpsonIpTester {
    private $printerIp = '10.1.0.12';
    private $builder;
    private $client;
    private $httpClient;
    private $responseParser;
    private $jobManager;
    private $printerManager;
    
    public function __construct() {
        $this->builder = new Builder();
        $this->client = new Client();
        $this->httpClient = new HttpClient();
        $this->responseParser = new ResponseParser();
        $this->jobManager = new JobManager($this->builder, $this->httpClient, $this->responseParser);
        $this->printerManager = new PrinterManager($this->builder, $this->httpClient, $this->responseParser);
        
        echo "🖨️  EPSON L4260 Series 网络测试\n";
        echo "打印机IP: {$this->printerIp}\n";
        echo str_repeat('=', 50) . "\n\n";
    }
    
    /**
     * 测试网络连接
     */
    public function testNetworkConnection() {
        echo "🔍 1. 测试网络连接...\n";
        
        // 测试ping连接
        if ($this->pingTest()) {
            echo "✓ Ping测试成功\n";
        } else {
            echo "❌ Ping测试失败\n";
            return false;
        }
        
        // 测试IPP端口
        if ($this->testIppPort()) {
            echo "✓ IPP端口631连接成功\n";
        } else {
            echo "❌ IPP端口631连接失败\n";
        }
        
        // 测试HTTP端口
        if ($this->testHttpPort()) {
            echo "✓ HTTP端口80连接成功\n";
        } else {
            echo "⚠️  HTTP端口80连接失败（可能正常）\n";
        }
        
        return true;
    }
    
    /**
     * 测试IPP服务
     */
    public function testIppService() {
        echo "\n🌐 2. 测试IPP服务...\n";
        
        $ippUris = [
            "ipp://{$this->printerIp}:631/ipp/print",
            "ipp://{$this->printerIp}/ipp/print",
            "http://{$this->printerIp}:631/ipp/print",
            "ipp://{$this->printerIp}:631/printers/EPSON_L4260_Series"
        ];
        
        foreach ($ippUris as $uri) {
            echo "测试URI: $uri\n";
            
            try {
                // 创建简单的测试任务来验证URI
                $job = new Job();
                $job->setName('连接测试');
                $job->setUsername('testuser');
                $job->setPrinterUri($uri);
                $job->addText('连接测试');
                
                echo "  ✓ URI格式验证成功\n";
                
                // 这里可以尝试获取打印机属性（需要实际连接）
                // $this->testPrinterAttributes($uri);
                
            } catch (Exception $e) {
                echo "  ❌ URI测试失败: " . $e->getMessage() . "\n";
            }
        }
        
        return $ippUris[0]; // 返回推荐的URI
    }
    
    /**
     * 创建实际打印测试
     */
    public function createPrintTest($uri = null) {
        if (!$uri) {
            $uri = "ipp://{$this->printerIp}:631/ipp/print";
        }
        
        echo "\n🖨️  3. 创建打印测试任务...\n";
        echo "使用URI: $uri\n\n";
        
        try {
            $job = new Job();
            $job->setName('EPSON L4260 网络打印测试');
            $job->setUsername('testuser');
            $job->setCopies(1);
            $job->setSides('one-sided');
            $job->setPrinterUri($uri);
            
            // 创建详细的测试内容
            $testContent = $this->createTestContent();
            $job->addText($testContent);
            
            echo "✓ 打印任务创建成功\n";
            echo "  - 任务名称: " . $job->getName() . "\n";
            echo "  - 打印机URI: " . $job->getPrinterUri() . "\n";
            echo "  - 用户名: " . $job->getUsername() . "\n";
            echo "  - 份数: " . $job->getCopies() . "\n";
            
            // 显示如何执行实际打印
            $this->showPrintInstructions($job);
            
            return $job;
            
        } catch (Exception $e) {
            echo "❌ 创建打印任务失败: " . $e->getMessage() . "\n";
            return null;
        }
    }
    
    /**
     * 执行实际打印（需要取消注释）
     */
    public function executePrint($job) {
        echo "\n🚀 4. 执行实际打印...\n";
        
        try {
            // 注意：这将发送实际的打印任务到打印机
            // 请确保打印机已准备好并有纸张
            
            echo "⚠️  准备发送打印任务到打印机...\n";
            echo "请确保：\n";
            echo "  - 打印机已开机\n";
            echo "  - 打印机有足够的纸张\n";
            echo "  - 打印机墨水充足\n";
            echo "\n按回车键继续，或Ctrl+C取消...";
            
            // 等待用户确认
            // readline();
            
            // 取消注释以下行来执行实际打印
            /*
            $result = $this->jobManager->send($job);
            
            if ($result) {
                echo "✅ 打印任务发送成功！\n";
                echo "任务ID: " . $result->getId() . "\n";
                echo "状态: " . $result->getState() . "\n";
            } else {
                echo "❌ 打印任务发送失败\n";
            }
            */
            
            echo "\n📝 要执行实际打印，请：\n";
            echo "1. 取消注释上面的打印代码\n";
            echo "2. 确保CUPS服务正在运行\n";
            echo "3. 重新运行此脚本\n";
            
        } catch (Exception $e) {
            echo "❌ 打印执行失败: " . $e->getMessage() . "\n";
            echo "文件: " . $e->getFile() . ":" . $e->getLine() . "\n";
        }
    }
    
    /**
     * 创建测试内容
     */
    private function createTestContent() {
        $content = "=== EPSON L4260 Series 网络打印测试 ===\n\n";
        $content .= "测试时间: " . date('Y-m-d H:i:s') . "\n";
        $content .= "打印机IP: {$this->printerIp}\n";
        $content .= "测试类型: 网络IPP打印\n\n";
        
        $content .= "连接信息:\n";
        $content .= "- 协议: Internet Printing Protocol (IPP)\n";
        $content .= "- 端口: 631\n";
        $content .= "- 网络: 局域网\n\n";
        
        $content .= "功能测试:\n";
        $content .= "✓ 网络连接\n";
        $content .= "✓ IPP协议通信\n";
        $content .= "✓ 文本打印\n";
        $content .= "✓ 中文字符: 爱普生网络打印机\n";
        $content .= "✓ 特殊字符: @#$%^&*()_+-=[]{}|;:,.<>?\n\n";
        
        $content .= "打印质量测试:\n";
        $content .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";
        $content .= "abcdefghijklmnopqrstuvwxyz\n";
        $content .= "0123456789\n\n";
        
        $content .= "如果您能清晰地看到这个完整的测试页面，\n";
        $content .= "说明EPSON L4260网络打印功能完全正常！\n\n";
        
        $content .= "技术信息:\n";
        $content .= "- PHP版本: " . PHP_VERSION . "\n";
        $content .= "- CUPS-IPP库版本: 最新\n";
        $content .= "- 操作系统: " . PHP_OS . "\n";
        
        return $content;
    }
    
    /**
     * 显示打印说明
     */
    private function showPrintInstructions($job) {
        echo "\n📋 打印说明:\n";
        echo "1. 当前创建的是测试任务，尚未发送到打印机\n";
        echo "2. 要执行实际打印，请调用 executePrint() 方法\n";
        echo "3. 或者取消注释 JobManager::send() 代码\n\n";
        
        echo "💡 代码示例:\n";
        echo "```php\n";
        echo "// 发送打印任务\n";
        echo "\$result = \$this->jobManager->send(\$job);\n";
        echo "echo \"任务ID: \" . \$result->getId();\n";
        echo "```\n\n";
    }
    
    /**
     * 网络诊断
     */
    public function networkDiagnostics() {
        echo "\n🔧 5. 网络诊断...\n";
        
        // 检查本机网络配置
        $this->checkLocalNetwork();
        
        // 检查路由
        $this->checkRouting();
        
        // 检查防火墙建议
        $this->checkFirewallSuggestions();
    }
    
    private function checkLocalNetwork() {
        echo "\n本机网络配置:\n";
        
        if (PHP_OS_FAMILY === 'Windows') {
            $output = [];
            exec('ipconfig /all', $output);
            
            foreach ($output as $line) {
                if (strpos($line, 'IPv4') !== false || 
                    strpos($line, '子网掩码') !== false || 
                    strpos($line, 'Subnet Mask') !== false ||
                    strpos($line, '默认网关') !== false ||
                    strpos($line, 'Default Gateway') !== false) {
                    echo "  " . trim($line) . "\n";
                }
            }
        } else {
            $output = [];
            exec('ip route show', $output);
            echo "路由信息:\n";
            foreach ($output as $line) {
                echo "  $line\n";
            }
        }
    }
    
    private function checkRouting() {
        echo "\n路由测试:\n";
        
        if (PHP_OS_FAMILY === 'Windows') {
            $command = "tracert -h 5 {$this->printerIp}";
        } else {
            $command = "traceroute -m 5 {$this->printerIp}";
        }
        
        echo "执行: $command\n";
        $output = [];
        exec($command . ' 2>&1', $output);
        
        $lineCount = 0;
        foreach ($output as $line) {
            if ($lineCount++ < 10) { // 限制输出行数
                echo "  $line\n";
            }
        }
    }
    
    private function checkFirewallSuggestions() {
        echo "\n🛡️  防火墙检查建议:\n";
        echo "- 确保端口631 (IPP) 未被阻止\n";
        echo "- 检查Windows防火墙设置\n";
        echo "- 确保打印机防火墙允许IPP连接\n";
        echo "- 检查路由器是否阻止了打印机通信\n";
    }
    
    // 辅助方法
    private function pingTest() {
        if (PHP_OS_FAMILY === 'Windows') {
            $command = "ping -n 3 -w 3000 {$this->printerIp}";
        } else {
            $command = "ping -c 3 -W 3 {$this->printerIp}";
        }
        
        $output = [];
        $returnCode = 0;
        exec($command . ' 2>&1', $output, $returnCode);
        
        return $returnCode === 0;
    }
    
    private function testIppPort() {
        return $this->testPort(631);
    }
    
    private function testHttpPort() {
        return $this->testPort(80);
    }
    
    private function testPort($port, $timeout = 5) {
        $connection = @fsockopen($this->printerIp, $port, $errno, $errstr, $timeout);
        if ($connection) {
            fclose($connection);
            return true;
        }
        return false;
    }
}

// 执行测试
echo "开始EPSON L4260 Series IP地址测试...\n\n";

$tester = new EpsonIpTester();

// 1. 测试网络连接
if ($tester->testNetworkConnection()) {
    
    // 2. 测试IPP服务
    $recommendedUri = $tester->testIppService();
    
    // 3. 创建打印测试
    $job = $tester->createPrintTest($recommendedUri);
    
    if ($job) {
        // 4. 可选：执行实际打印
        $tester->executePrint($job);
    }
    
    // 5. 网络诊断
    $tester->networkDiagnostics();
    
} else {
    echo "\n❌ 网络连接失败，请检查：\n";
    echo "1. 打印机是否开机\n";
    echo "2. 网络连接是否正常\n";
    echo "3. IP地址是否正确\n";
    echo "4. 防火墙设置\n";
}

echo "\n" . str_repeat('=', 50) . "\n";
echo "✅ 测试完成！\n";
echo "\n💡 提示：如需执行实际打印，请取消注释相关代码并重新运行。\n";